Instalar librerias necesarias (en modo silencioso -q):

[1]:
!wget -q https://raw.githubusercontent.com/arqlm/arqlm.github.io/main/_static/libraries.txt
!pip install -q -r /content/libraries.txt
!pip install -q --upgrade plotly[kaleido]
!rm -r /content/libraries.txt
!rm -r /content/sample_data/ ## Esta linea no es necesaria cuando no se trabaja en colab.google
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.9/7.9 MB 35.8 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 51.5/51.5 kB 1.7 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 9.6/9.6 MB 64.7 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 51.3/51.3 kB 2.9 MB/s eta 0:00:00

[1]:
## Importar librerías

import pandas as pd
import numpy as np
import base64
import datetime
import io

import plotly.io as pio
import plotly.graph_objects as go
import plotly.express as px
import plotly.offline as py

# pio.renderers.default = "colab"
pio.renderers.default = "notebook" # usar esta linea en jupyter notebook o vscode


5. Definición de unidades o dominios de estimación

La decisión de estacionariedad es clave para la inferencia estadística. La inferencia debe realizarse utilizando muestras que pertenezcan una misma población (dominio). Además, en el espacio, las propiedades estadísticas de las ubicaciones utilizadas para inferir información (ley de mineral) una ubicación no muestreada deben ser consistentes, para evitar sesgos. Si las propiedades espaciales de la variable cambian con la ubicación, la inferencia se vuelve problemática.

Para abordar este problema, se definen dominios. En el contexto del modelado en geociencias, estos dominios deben mostrar propiedades similares desde el punto de vista geológico, y muchas veces también deben mostrar consistencia respecto a la variable de respuesta. Por ejemplo, en depósitos minerales, un dominio debe agrupar ubicaciones con una distribución de leyes similar.

Así, los dominios estacionarios se definen en base a las propiedades geológicas y a las propiedades estadísticas de la variable estudiada. Llamaremos a estos dominios “unidades geológicas” cuando el problema estadístico se encuentre el contexto minero de estimación de recursos.

Definición de unidades geológicas (dominios) para la estimación de recursos (no es una receta, sino primeros pasos que requieren iteraciones adicionales con aporte geológico):

    1. Realizar un análisis estadístico de las leyes relevantes por categoría de atributo geológico (típicamente litología, tipo de alteración y zona mineral).

    2. Identificar categorías que muestran un comportamiento similar en términos de la distribución estadística, observando los gráficos de probabilidad.

    3. Unir categorías geológicas, considerando la similitud estadística, su ubicación espacial y la coherencia geológica. Por ejemplo, agrupar tipos de rocas similares y no unir materiales que requieran diferentes procesos de tratamiento.

    4. Actualizar las estadísticas y revisar.

Los primeros dos pasos ya fueron realizados en las secciones anteriores (ver Búsqueda de controles geológicos). Procedamos a continuación con el punto 3.


6. Creación de Unidades Geológicas

6.1. Carga de archivos

[2]:
import pandas as pd
import numpy as np

import warnings
warnings.simplefilter(action="ignore")

# Cargar base de datos en pandas
DH = pd.read_csv('EvYacData.csv', sep=',', encoding='latin1')
DH['cu_pct'][DH['cu_pct'] <= 0] = np.nan

DH

[2]:
Este Norte Elevación au_ppm ag_ppm cu_pct aucn_ppm cucn_ppm Zmin Alte Lito
0 472186.686 6925804.447 4220.763 -99.00 -99.0 NaN -99.0 -99.0 OXI ILL_CLO IBX_MM
1 472187.202 6925805.493 4213.861 0.30 2.3 0.011 -99.0 -99.0 OXI ILL_CLO IBX_MM
2 472187.343 6925805.770 4211.986 0.47 16.2 0.032 -99.0 -99.0 OXI ILL_CLO IBX_MM
3 472187.493 6925806.060 4210.013 0.31 2.3 0.018 -99.0 -99.0 OXI ILL_CLO IBX_MM
4 472187.642 6925806.351 4208.040 0.29 2.1 0.010 -99.0 -99.0 OXI ILL_CLO IBX_MM
... ... ... ... ... ... ... ... ... ... ... ...
77836 471293.198 6925823.101 3761.674 0.03 1.0 0.002 -99.0 -99.0 BACK PROP ECS
77837 471293.540 6925824.040 3759.942 0.01 0.7 0.001 -99.0 -99.0 BACK PROP ECS
77838 471293.882 6925824.980 3758.209 0.01 0.4 0.001 -99.0 -99.0 BACK PROP ECS
77839 471294.224 6925825.920 3756.477 0.06 1.3 0.004 -99.0 -99.0 BACK PROP ECS
77840 471294.607 6925826.972 3754.538 0.06 0.5 0.003 -99.0 -99.0 BACK PROP ECS

77841 rows × 11 columns

Continuamos creando una nueva variable en nuestra base de datos en donde guardaremos la definición de Unidades Geologicas (UG) que, por defecto, tendra un valor no definido, -99:

[3]:
DH['UG'] = -99
DH
[3]:
Este Norte Elevación au_ppm ag_ppm cu_pct aucn_ppm cucn_ppm Zmin Alte Lito UG
0 472186.686 6925804.447 4220.763 -99.00 -99.0 NaN -99.0 -99.0 OXI ILL_CLO IBX_MM -99
1 472187.202 6925805.493 4213.861 0.30 2.3 0.011 -99.0 -99.0 OXI ILL_CLO IBX_MM -99
2 472187.343 6925805.770 4211.986 0.47 16.2 0.032 -99.0 -99.0 OXI ILL_CLO IBX_MM -99
3 472187.493 6925806.060 4210.013 0.31 2.3 0.018 -99.0 -99.0 OXI ILL_CLO IBX_MM -99
4 472187.642 6925806.351 4208.040 0.29 2.1 0.010 -99.0 -99.0 OXI ILL_CLO IBX_MM -99
... ... ... ... ... ... ... ... ... ... ... ... ...
77836 471293.198 6925823.101 3761.674 0.03 1.0 0.002 -99.0 -99.0 BACK PROP ECS -99
77837 471293.540 6925824.040 3759.942 0.01 0.7 0.001 -99.0 -99.0 BACK PROP ECS -99
77838 471293.882 6925824.980 3758.209 0.01 0.4 0.001 -99.0 -99.0 BACK PROP ECS -99
77839 471294.224 6925825.920 3756.477 0.06 1.3 0.004 -99.0 -99.0 BACK PROP ECS -99
77840 471294.607 6925826.972 3754.538 0.06 0.5 0.003 -99.0 -99.0 BACK PROP ECS -99

77841 rows × 12 columns

Como ya se mencionó anteriormente, la definición de UGs es un proceso iterativo. Partiremos definiendo tres UGs a partir de las Zonas Minerales. La creación de UGs requiere un uso intensivo de la lógica y, por lo tanto, de operadores lógicos. Escencialmente, en esta primera etapa nos interesa separar los oxidos, de la zona mixta y transcicion —las cuales uniremos en una sola unidad—, del resto de las muestras (0 —no definido—, probablemente esteril o gravas):

[ ]:
## 1.- Si la muestra pertenecen a la zona de transicion o el background, definimos temporalmente una UG de mayor ley, 3
DH['UG'][(DH['Zmin'] == 'TRANS') | (DH['Zmin'] == 'BACK')] = 2

## 2.- Si la muestra pertenecen a la zona de oxidos, definimos temporalmente una UG de ley intermedia, 2
DH['UG'][(DH['Zmin'] == 'OXI')] = 1

## 3.- Finalmente, si la muestra pertenecen no pertenece ni a la UG 3 ni a la 2, entonces las muestras son las de menor ley y las agrupamos en la UG 1
## DH['UG'][(DH['Zmin'] != 'OXI') & (DH['Zmin'] != 'TRANS') & (DH['Zmin'] != 'BACK')] = 0 ## Podemos usar este comando, o equivalentemente:
DH['UG'][(DH['UG'] != 2) & (DH['UG'] != 1)] = 0

## Mostramos el resultado final
DH
Este Norte Elevación au_ppm ag_ppm cu_pct aucn_ppm cucn_ppm Zmin Alte Lito UG
0 472186.686 6925804.447 4220.763 -99.00 -99.0 NaN -99.0 -99.0 OXI ILL_CLO IBX_MM 2
1 472187.202 6925805.493 4213.861 0.30 2.3 0.011 -99.0 -99.0 OXI ILL_CLO IBX_MM 2
2 472187.343 6925805.770 4211.986 0.47 16.2 0.032 -99.0 -99.0 OXI ILL_CLO IBX_MM 2
3 472187.493 6925806.060 4210.013 0.31 2.3 0.018 -99.0 -99.0 OXI ILL_CLO IBX_MM 2
4 472187.642 6925806.351 4208.040 0.29 2.1 0.010 -99.0 -99.0 OXI ILL_CLO IBX_MM 2
... ... ... ... ... ... ... ... ... ... ... ... ...
77836 471293.198 6925823.101 3761.674 0.03 1.0 0.002 -99.0 -99.0 BACK PROP ECS 3
77837 471293.540 6925824.040 3759.942 0.01 0.7 0.001 -99.0 -99.0 BACK PROP ECS 3
77838 471293.882 6925824.980 3758.209 0.01 0.4 0.001 -99.0 -99.0 BACK PROP ECS 3
77839 471294.224 6925825.920 3756.477 0.06 1.3 0.004 -99.0 -99.0 BACK PROP ECS 3
77840 471294.607 6925826.972 3754.538 0.06 0.5 0.003 -99.0 -99.0 BACK PROP ECS 3

77841 rows × 12 columns

[5]:
import numpy as np
import plotly.graph_objects as go
import scipy.stats as stats
from statsmodels.distributions.empirical_distribution import ECDF

# Plot all probability curves in the same figure
fig = go.Figure()
for category in sorted(DH.groupby('UG').groups.keys()):
    values = DH.groupby('UG').get_group(category)['cu_pct'].dropna().values
    # Sort values
    values_sorted = np.sort(values)
    n = len(values_sorted)
    cumprob = (np.arange(1, n+1) - 0.5) / n
    normal_scores = stats.norm.ppf(cumprob)
    fig.add_trace(go.Scatter(
        x=values_sorted,
        y=normal_scores,
        mode='markers',
        marker=dict(size=5, opacity=0.7),
        name=str(category)
    ))

# Custom y-axis to match imagen.png
y_ticks = stats.norm.ppf([0.0001, 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 0.99999])
y_ticklabels = ['0.001%','1%', '5%', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '95%', '99%', '99.999%']

fig.update_layout(
    title="Distribuciones preliminares de Dominios",
    title_x=0.5,
    xaxis_title='Cu [%]',
    xaxis=dict(
        type='log',
    ),
    yaxis_title='Probabilidad',
    yaxis=dict(
        tickmode='array',
        tickvals=y_ticks,
        ticktext=y_ticklabels,
        range=[stats.norm.ppf(0.00001), stats.norm.ppf(0.99999)]
    ),
    width=800,
    height=600,
    font_family="Times New Roman",
    font_size=14,
    font_color="black",
    plot_bgcolor='white',
    autosize=False,
    showlegend=True
)
fig.update_layout(
    legend_title_text='UGs',
    legend=dict(
        itemsizing='constant',
        font=dict(size=14),
        bgcolor='rgba(255,255,255,0.8)',
        bordercolor='black',
        borderwidth=1
    )
)
fig.update_xaxes(gridcolor='rgba(0,0,0,0.1)')
fig.update_yaxes(gridcolor='rgba(0,0,0,0.1)')
fig.update_layout(hovermode=False)
fig.show()


A continuacion, haremos un zoom a las dos dsitribuciones principales, realizando lo que se denomina como un quiebre de las distribuciones: “romperemos” estas distribuciones de acuerdo a una segunda variable geológica: en este caso, por la alteración:

A continuacion, haremos un zoom a las dos dsitribuciones principales, realizando lo que se denomina como un quiebre de las distribuciones: “romperemos” estas distribuciones de acuerdo a una segunda variable geológica: en este caso, por la alteración:

Resumen de pasos para subdividir UGs según alteración:

  • Para UG 2:

    1. Si la muestra pertenece a UG 2 y la alteración es POT_BT, POT_KFELD o BACK → asignar UG 23 (máxima ley).

    2. Si la muestra pertenece a UG 2 y la alteración es SER_CLO o QTZ_SER_PY → asignar UG 22 (mediana ley).

    3. El resto de UG 3 → asignar UG 21 (resto).

  • Para UG 1:

    1. Si la muestra pertenece a UG 1 y la alteración es SER_CLO o QTZ_SER_PY → asignar UG 13 (máxima ley).

    2. Si la muestra pertenece a UG 1 y la alteración es PROP o ILL_CLO → asignar UG 12 (mediana ley).

    3. El resto de UG 1 → asignar UG 11 (resto).

[ ]:
##### Para la UG 3 ##########################################################################

## 1.- Si la muestra pertenecen a la UG 2, generamos una distribucion de maxima ley, UG 23 usando las categorías de alteración POT_BT, POT_KFELD, y BACK
DH['UG'][(DH['UG'] == 2) & ((DH['Alte'] == 'POT_BT') | (DH['Alte'] == 'POT_KFELD') | (DH['Alte'] == 'BACK'))] = 23

## 2.- Si la muestra pertenecen a la UG 2, generamos una distribucion de mediana ley, UG 22 usando las categorías de alteración SER_CLO y QTZ_SER_PY
DH['UG'][(DH['UG'] == 2) & ((DH['Alte'] == 'SER_CLO') | (DH['Alte'] == 'QTZ_SER_PY'))] = 22

## 3.- Finalmente, el resto pasa a ser definido como UG 21
DH['UG'][(DH['UG'] == 2)] = 21

##### Para la UG 1 ##########################################################################

## 1.- Si la muestra pertenecen a la UG 1, generamos una distribucion de maxima ley, UG 13 usando las categorías de alteración POT_BT, POT_KFELD, y BACK
DH['UG'][(DH['UG'] == 1) & ((DH['Alte'] == 'SER_CLO') | (DH['Alte'] == 'QTZ_SER_PY'))] = 13

## 2.- Si la muestra pertenecen a la UG 1, generamos una distribucion de mediana ley, UG 12 usando las categorías de alteración PROP y ILL_CLO
DH['UG'][(DH['UG'] == 1) & ((DH['Alte'] == 'PROP') | (DH['Alte'] == 'ILL_CLO'))] = 12

## 3.- Finalmente, el resto pasa a ser definido como UG 11
DH['UG'][(DH['UG'] == 1)] = 11

## Mostramos el resultado final
DH
Este Norte Elevación au_ppm ag_ppm cu_pct aucn_ppm cucn_ppm Zmin Alte Lito UG
0 472186.686 6925804.447 4220.763 -99.00 -99.0 NaN -99.0 -99.0 OXI ILL_CLO IBX_MM 22
1 472187.202 6925805.493 4213.861 0.30 2.3 0.011 -99.0 -99.0 OXI ILL_CLO IBX_MM 22
2 472187.343 6925805.770 4211.986 0.47 16.2 0.032 -99.0 -99.0 OXI ILL_CLO IBX_MM 22
3 472187.493 6925806.060 4210.013 0.31 2.3 0.018 -99.0 -99.0 OXI ILL_CLO IBX_MM 22
4 472187.642 6925806.351 4208.040 0.29 2.1 0.010 -99.0 -99.0 OXI ILL_CLO IBX_MM 22
... ... ... ... ... ... ... ... ... ... ... ... ...
77836 471293.198 6925823.101 3761.674 0.03 1.0 0.002 -99.0 -99.0 BACK PROP ECS 31
77837 471293.540 6925824.040 3759.942 0.01 0.7 0.001 -99.0 -99.0 BACK PROP ECS 31
77838 471293.882 6925824.980 3758.209 0.01 0.4 0.001 -99.0 -99.0 BACK PROP ECS 31
77839 471294.224 6925825.920 3756.477 0.06 1.3 0.004 -99.0 -99.0 BACK PROP ECS 31
77840 471294.607 6925826.972 3754.538 0.06 0.5 0.003 -99.0 -99.0 BACK PROP ECS 31

77841 rows × 12 columns

[7]:
import numpy as np
import plotly.graph_objects as go
import scipy.stats as stats
from statsmodels.distributions.empirical_distribution import ECDF

# Plot all probability curves in the same figure
fig = go.Figure()
for category in sorted(DH.groupby('UG').groups.keys()):
    values = DH.groupby('UG').get_group(category)['cu_pct'].dropna().values
    # Sort values
    values_sorted = np.sort(values)
    n = len(values_sorted)
    cumprob = (np.arange(1, n+1) - 0.5) / n
    normal_scores = stats.norm.ppf(cumprob)
    fig.add_trace(go.Scatter(
        x=values_sorted,
        y=normal_scores,
        mode='markers',
        marker=dict(size=5, opacity=0.7),
        name=str(category)
    ))

# Custom y-axis to match imagen.png
y_ticks = stats.norm.ppf([0.0001, 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 0.99999])
y_ticklabels = ['0.001%','1%', '5%', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '95%', '99%', '99.999%']

fig.update_layout(
    title="Distribuciones preliminares de Dominios",
    title_x=0.5,
    xaxis_title='Cu [%]',
    xaxis=dict(
        type='log',
    ),
    yaxis_title='Probabilidad',
    yaxis=dict(
        tickmode='array',
        tickvals=y_ticks,
        ticktext=y_ticklabels,
        range=[stats.norm.ppf(0.00001), stats.norm.ppf(0.99999)]
    ),
    width=800,
    height=600,
    font_family="Times New Roman",
    font_size=14,
    font_color="black",
    plot_bgcolor='white',
    autosize=False,
    showlegend=True
)
fig.update_layout(
    legend_title_text='UGs',
    legend=dict(
        itemsizing='constant',
        font=dict(size=14),
        bgcolor='rgba(255,255,255,0.8)',
        bordercolor='black',
        borderwidth=1
    )
)
fig.update_xaxes(gridcolor='rgba(0,0,0,0.1)')
fig.update_yaxes(gridcolor='rgba(0,0,0,0.1)')
fig.update_layout(hovermode=False)
fig.show()


En cualquier punto, es importante generar las estadisticas basicas de los resultados preliminares. Esto nos ayuda a tomar decisiones sobre que UGs juntar y cuales no, de acuerdo a las medias, varianzas y cantidad de muestras por Unidad

[8]:
stats_by_mine = DH.groupby(['UG']).describe().round(2)
stats_by_mine['cu_pct']
[8]:
count mean std min 25% 50% 75% max
UG
1 3030.0 0.01 0.02 0.0 0.00 0.00 0.00 0.27
21 2187.0 0.08 0.14 0.0 0.02 0.03 0.05 1.82
22 5325.0 0.04 0.06 0.0 0.01 0.02 0.04 0.73
23 9754.0 0.07 0.10 0.0 0.02 0.03 0.05 1.50
31 14857.0 0.06 0.14 0.0 0.00 0.02 0.06 8.00
32 8812.0 0.14 0.16 0.0 0.04 0.09 0.19 2.75
33 32942.0 0.24 0.24 0.0 0.11 0.20 0.32 8.30

De manera de tener unidades balanceadas de un punto de vista del número de muestras y considerando a su vez las medias de las unidades preliminares, finalmente tomamos la siguiente decisión:

Reagrupación de unidades preliminares en Unidades Geológicas Finales:

  • UG de menor ley: Asignar UG 1 a todas las muestras con UG igual a 1.

  • UG con segunda menor ley: Asignar UG 2 a todas las muestras con UG igual a 22, 21, 23 o 31.

  • UG con segunda mayor ley: Asignar UG 3 a todas las muestras con UG igual a 32.

  • UG con mayor ley: Asignar UG 4 a todas las muestras con UG igual a 33.

[9]:
## 1.- UG de menor ley
DH['UG'][(DH['UG'] == 1)] = 1

## 2.- UG con segunda menor ley
DH['UG'][(DH['UG'] == 22) | (DH['UG'] == 21) | (DH['UG'] == 23) | (DH['UG'] == 31)] = 2

## 3.- UG con segunda mayor ley
DH['UG'][(DH['UG'] == 32)] = 3

## 4.- UG con mayor ley
DH['UG'][(DH['UG'] == 33)] = 4

DH
[9]:
Este Norte Elevación au_ppm ag_ppm cu_pct aucn_ppm cucn_ppm Zmin Alte Lito UG
0 472186.686 6925804.447 4220.763 -99.00 -99.0 NaN -99.0 -99.0 OXI ILL_CLO IBX_MM 2
1 472187.202 6925805.493 4213.861 0.30 2.3 0.011 -99.0 -99.0 OXI ILL_CLO IBX_MM 2
2 472187.343 6925805.770 4211.986 0.47 16.2 0.032 -99.0 -99.0 OXI ILL_CLO IBX_MM 2
3 472187.493 6925806.060 4210.013 0.31 2.3 0.018 -99.0 -99.0 OXI ILL_CLO IBX_MM 2
4 472187.642 6925806.351 4208.040 0.29 2.1 0.010 -99.0 -99.0 OXI ILL_CLO IBX_MM 2
... ... ... ... ... ... ... ... ... ... ... ... ...
77836 471293.198 6925823.101 3761.674 0.03 1.0 0.002 -99.0 -99.0 BACK PROP ECS 2
77837 471293.540 6925824.040 3759.942 0.01 0.7 0.001 -99.0 -99.0 BACK PROP ECS 2
77838 471293.882 6925824.980 3758.209 0.01 0.4 0.001 -99.0 -99.0 BACK PROP ECS 2
77839 471294.224 6925825.920 3756.477 0.06 1.3 0.004 -99.0 -99.0 BACK PROP ECS 2
77840 471294.607 6925826.972 3754.538 0.06 0.5 0.003 -99.0 -99.0 BACK PROP ECS 2

77841 rows × 12 columns

[10]:
import numpy as np
import plotly.graph_objects as go
import scipy.stats as stats
from statsmodels.distributions.empirical_distribution import ECDF

# Plot all probability curves in the same figure
fig = go.Figure()
for category in sorted(DH.groupby('UG').groups.keys()):
    values = DH.groupby('UG').get_group(category)['cu_pct'].dropna().values
    # Sort values
    values_sorted = np.sort(values)
    n = len(values_sorted)
    cumprob = (np.arange(1, n+1) - 0.5) / n
    normal_scores = stats.norm.ppf(cumprob)
    fig.add_trace(go.Scatter(
        x=values_sorted,
        y=normal_scores,
        mode='markers',
        marker=dict(size=5, opacity=0.7),
        name=str(category)
    ))

# Custom y-axis to match imagen.png
y_ticks = stats.norm.ppf([0.0001, 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 0.99999])
y_ticklabels = ['0.001%','1%', '5%', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '95%', '99%', '99.999%']

fig.update_layout(
    title="Distribución Estadística de Unidades Geológicas",
    title_x=0.5,
    xaxis_title='Cu [%]',
    xaxis=dict(
        type='log',
    ),
    yaxis_title='Probabilidad',
    yaxis=dict(
        tickmode='array',
        tickvals=y_ticks,
        ticktext=y_ticklabels,
        range=[stats.norm.ppf(0.00001), stats.norm.ppf(0.99999)]
    ),
    width=800,
    height=600,
    font_family="Times New Roman",
    font_size=14,
    font_color="black",
    plot_bgcolor='white',
    autosize=False,
    showlegend=True
)
fig.update_layout(
    legend_title_text='UGs',
    legend=dict(
        itemsizing='constant',
        font=dict(size=14),
        bgcolor='rgba(255,255,255,0.8)',
        bordercolor='black',
        borderwidth=1
    )
)
fig.update_xaxes(gridcolor='rgba(0,0,0,0.1)')
fig.update_yaxes(gridcolor='rgba(0,0,0,0.1)')
fig.update_layout(hovermode=False)
fig.show()


[11]:
stats_by_mine = DH.groupby(['UG']).describe().round(2)
stats_by_mine['cu_pct']
[11]:
count mean std min 25% 50% 75% max
UG
1 3030.0 0.01 0.02 0.0 0.00 0.00 0.00 0.27
2 32123.0 0.06 0.12 0.0 0.01 0.02 0.06 8.00
3 8812.0 0.14 0.16 0.0 0.04 0.09 0.19 2.75
4 32942.0 0.24 0.24 0.0 0.11 0.20 0.32 8.30

Procedemos a desplegar espacialmente nuestras Unidades Geológicas (UG) en el espacio 3D, de manera de verificar que ellas hagan sentido desde un punto de vista espacial (que se encuentren relativamente contiguas las muestras pertenecientes a una misma UG y que no se encuentren truncadas las UGs entre ellas de forma tan evidente).

[12]:
DH["UG"] = DH["UG"].astype(str)
fig = px.scatter_3d(DH, x='Este', y='Norte', z='Elevación', color='UG',category_orders={'UG': sorted(DH.groupby('UG').groups.keys())})
fig.update_traces(marker=dict(size=2.0))

# Mejor estilo para leyenda
fig.update_layout(
    title_text='Unidades Geológicas para Cu',
    legend_title_text='UGs',
    legend=dict(
        itemsizing='constant',
        font=dict(size=14),
        bgcolor='rgba(255,255,255,0.8)',
        bordercolor='black',
        borderwidth=1
    )
)

fig.show()

Omitimos para este caso el uso de la variable Litología, de modo de no complejizar aún más esta demostración.


6.2. Exportar resultados

Finalmente, exportamos nuestros resultados para no tener que volver a escribir generar estas variables de UGs en los próximos flujos de trabajo.

[13]:
DH.to_csv('Data_sin_compositar_con_UGs.csv',index=False)